package com.siyoumi.app.modules.app_book.service;

import com.siyoumi.app.entity.*;
import com.siyoumi.app.modules.app_book.vo.VaBookSet;
import com.siyoumi.app.modules.app_book.vo.VaBookSetDay;
import com.siyoumi.app.modules.app_book.vo.VoBookSetAudit;
import com.siyoumi.app.service.BookSetDayService;
import com.siyoumi.app.service.BookSetService;
import com.siyoumi.component.XApp;
import com.siyoumi.component.XSpringContext;
import com.siyoumi.component.http.InputData;
import com.siyoumi.component.http.XHttpContext;
import com.siyoumi.exception.EnumSys;
import com.siyoumi.mybatispuls.JoinWrapperPlus;
import com.siyoumi.service.IWebService;
import com.siyoumi.util.XDate;
import com.siyoumi.util.XReturn;
import com.siyoumi.util.XStr;
import com.siyoumi.validator.XValidator;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

//
@Slf4j
@Service
public class SvcBookSet
        implements IWebService {
    static public SvcBookSet getBean() {
        return XSpringContext.getBean(SvcBookSet.class);
    }

    static public BookSetService getApp() {
        return BookSetService.getBean();
    }

    /**
     * 获取第1个套餐
     *
     * @param storeId
     */
    public BookSet getFirst(String storeId) {
        JoinWrapperPlus<BookSet> query = SvcBookSet.getBean().listQuery();
        query.eq("bset_store_id", storeId)
                .eq("bset_enable", 1); //上架
        return SvcBookSet.getApp().first(query);
    }

    public List<Map<String, Object>> getList(String storeId) {
        return getList(storeId, null);
    }

    /**
     * 只显示已上架
     *
     * @param storeId
     */
    public List<Map<String, Object>> getList(String storeId, String spuId) {
        JoinWrapperPlus<BookSet> query = listQuery();
        query.eq("main.bset_store_id", storeId)
                .eq("main.bset_enable", 1);
        query.setAs("main");
        if (XStr.hasAnyText(spuId)) { //房间
            String sqlExists = "SELECT 1 FROM wx_app_x.t_book_spu_set WHERE bset_set_id = main.bset_id AND bset_spu_id = {0}";
            query.exists(sqlExists, spuId);
        }
        query.select("bset_id", "bset_name", "bset_day_price", "bset_desc");

        return getApp().getMaps(query);
    }

    public XReturn validCommon(BookSet entity) {
        if (entity == null) {
            return EnumSys.ERR_VAL.getR("set_id异常");
        }
        if (entity.getBset_del() != 0) {
            return EnumSys.ERR_VAL.getR("套餐不存在");
        }

        return EnumSys.OK.getR();
    }

    /**
     * 是否有效
     */
    public XReturn valid(BookSet entity) {
        XReturn r = validCommon(entity);
        if (r.err()) {
            return r;
        }
        if (!entity.enable()) {
            return EnumSys.ERR_VAL.getR("套餐已下架");
        }

        return EnumSys.OK.getR();
    }

    public XReturn canEdit(BookSet entity) {
        XReturn r = validCommon(entity);
        if (r.err()) {
            return r;
        }
        if (entity.enable()) {
            return EnumSys.ERR_VAL.getR("套餐已上架");
        }

        return EnumSys.OK.getR();
    }


    public JoinWrapperPlus<BookSet> listQuery() {
        return listQuery(InputData.getIns());
    }

    /**
     * select
     *
     * @return query
     */
    public JoinWrapperPlus<BookSet> listQuery(InputData inputData) {
        String name = inputData.input("name");

        JoinWrapperPlus<BookSet> query = getApp().join();
        query.eq("bset_x_id", XHttpContext.getX())
                .eq("bset_del", 0);
        //排序
        query.orderByAsc("bset_order")
                .orderByDesc("bset_id");

        if (XStr.hasAnyText(name)) { //名称
            query.like("bset_name", name);
        }

        return query;
    }

    /**
     * 每日库存
     *
     * @return query
     */
    public JoinWrapperPlus<BookSetDay> listDayQuery(String setId) {
        JoinWrapperPlus<BookSetDay> query = BookSetDayService.getBean().join();
        query.eq("bsday_x_id", XHttpContext.getX())
                .eq("bsday_set_id", setId);

        return query;
    }

    /**
     * 套餐日期区间内的加价总数
     *
     * @param setId
     */
    public BigDecimal dayPriceTotal(String setId, LocalDateTime dateBegin, LocalDateTime dateEnd) {
        JoinWrapperPlus<BookSetDay> query = listDayQuery(setId);
        query.between("bsday_date", dateBegin, dateEnd);

        return BookSetDayService.getBean().sum(query, "bsday_add_price");
    }

    public List<BookSetDay> listDay(String setId, List<LocalDateTime> dates) {
        JoinWrapperPlus<BookSetDay> query = listDayQuery(setId);
        query.in("bsday_date", dates);

        return BookSetDayService.getBean().get(query);
    }

    public XReturn edit(InputData inputData, VaBookSet vo) {
        List<String> ignoreField = new ArrayList<>();
        if (inputData.isAdminEdit()) {
            BookSet entitySet = getApp().getEntity(inputData.getID());
            XValidator.err(canEdit(entitySet));
        }

        return XApp.getTransaction().execute(status -> {
            XReturn r = getApp().saveEntity(inputData, vo, true, ignoreField);
            return r;
        });
    }

    /**
     * 删除
     */
    @SneakyThrows
    @Transactional(propagation = Propagation.MANDATORY)
    public XReturn delete(List<String> ids) {
        XReturn r = XReturn.getR(0);

        JoinWrapperPlus<BookSet> query = listQuery();
        query.in(BookSet.tableKey(), ids);
        List<BookSet> listSpu = getApp().get(query);
        for (BookSet entity : listSpu) {
            if (entity.getBset_enable() == 1) {
                return XReturn.getR(20108, entity.getBset_name() + "已上架不能删除");
            }
        }

        getApp().delete(ids);

        return r;
    }


    /**
     * 审核
     *
     * @param vo
     */
    @Transactional(rollbackFor = Exception.class)
    public XReturn audit(VoBookSetAudit vo) {
        JoinWrapperPlus<BookSet> query = listQuery();
        query.in(BookSet.tableKey(), vo.getIds())
                .eq("bset_store_id", vo.getStore_id());
        List<BookSet> list = getApp().get(query);
        if (list.isEmpty()) {
            return EnumSys.OK.getR();
        }

        for (BookSet entity : list) {
            if (Objects.equals(entity.getBset_enable(), vo.getEnable())) {
                continue;
            }
            if (vo.getEnable() == 1) {
                if (entity.getBset_day_price().compareTo(BigDecimal.ZERO) < 0) {
                    XValidator.err(EnumSys.ERR_VAL.getR(entity.getBset_name() + "：价格不能小于0，不能上架"));
                }
            }

            BookSet entityUpdate = new BookSet();
            entityUpdate.setBset_id(entity.getKey());
            entityUpdate.setBset_enable(vo.getEnable());
            entityUpdate.setBset_enable_date(XDate.now());
            getApp().updateById(entityUpdate);
        }

        SvcBookStore.getBean().updateSetIdFirst(list.get(0).getBset_store_id());

        return EnumSys.OK.getR();
    }


    /**
     * 批量修改日期库存
     *
     * @param vo
     */
    public XReturn editBatchDay(VaBookSetDay vo) {
        BookSet entitySet = getApp().getEntity(vo.getBspud_set_id());
        XValidator.err(canEdit(entitySet));

        //日期更新库存和加价
        List<LocalDateTime> dateList = XDate.getDateList(vo.getBegin_date(), vo.getEnd_date(), vo.getWeek());
        List<BookSetDay> listSpuDay = listDay(vo.getBspud_set_id(), dateList);
        for (LocalDateTime date : dateList) {
            BookSetDay entity = listSpuDay.stream().filter(item -> item.getBsday_date().equals(date)).findFirst().orElse(null);

            BookSetDay entityUpdate = new BookSetDay();
            if (entity == null) {
                entityUpdate.setAutoID();
                entityUpdate.setBsday_set_id(entitySet.getKey());
                entityUpdate.setBsday_x_id(entitySet.getBset_x_id());
                entityUpdate.setBsday_date(date);
            }
            entityUpdate.setBsday_add_price_breakfast(vo.getBsday_add_price_breakfast());
            entityUpdate.setBsday_add_price_lunch(vo.getBsday_add_price_lunch());
            entityUpdate.setBsday_add_price_dinner(vo.getBsday_add_price_dinner());
            entityUpdate.setBsday_add_price(vo.getBsday_add_price_breakfast().add(vo.getBsday_add_price_lunch()).add(vo.getBsday_add_price_dinner()));
            BookSetDayService.getBean().saveOrUpdatePassEqualField(entity, entityUpdate);
        }

        return EnumSys.OK.getR();
    }
}
